home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / System / Swatch / Development / swatch 1.7 / info.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-09  |  9.0 KB  |  408 lines  |  [TEXT/KAHL]

  1. /**
  2.  
  3.     info.c
  4.     Copyright (c) 1990-1992, joe holt
  5.  
  6.  **/
  7.  
  8.  
  9. /**-----------------------------------------------------------------------------
  10.  **
  11.  **    Headers
  12.  **
  13.  **/
  14.  
  15. #ifndef __content__
  16. #include "content.h"
  17. #endif
  18. #ifndef __ctypes__
  19. #include "ctypes.h"
  20. #endif
  21. #ifndef __display__
  22. #include "display.h"
  23. #endif
  24. #ifndef __heap__
  25. #include "heap.h"
  26. #endif
  27. #ifndef __heap_list__
  28. #include "heap_list.h"
  29. #endif
  30. #ifndef __info__
  31. #include "info.h"
  32. #endif
  33. #ifndef __prefs__
  34. #include "prefs.h"
  35. #endif
  36. #ifndef __pstring__
  37. #include "pstring.h"
  38. #endif
  39. #ifndef __resources__
  40. #include "resources.h"
  41. #endif
  42. #ifndef __swatch__
  43. #include "swatch.h"
  44. #endif
  45. #ifndef __window__
  46. #include "window.h"
  47. #endif
  48.  
  49.  
  50. /**-----------------------------------------------------------------------------
  51.  **
  52.  ** Private Constants
  53.  **
  54.  **/
  55.  
  56. // resources describing which low memory globals are saved
  57.  
  58. #define OLD_lmem    -16459
  59. #define NEW_lmem    -16458
  60.  
  61.  
  62. /**-----------------------------------------------------------------------------
  63.  **
  64.  ** Private Variables
  65.  **
  66.  **/
  67.  
  68. typedef struct {
  69.     int16 run_length;
  70.     Ptr start_address;
  71. } lmem_elem_t;
  72.  
  73. static lmem_elem_t *lmem_ptr;
  74. static Ptr low_memory;
  75. static Handle top_map_hdl;
  76.  
  77. extern int16 mbox_type;
  78. extern Heap_info_t *mbox_heap;
  79.  
  80.  
  81. /**-----------------------------------------------------------------------------
  82.  **
  83.  ** Private Functions
  84.  **
  85.  **/
  86.  
  87. static Boolean set_up_process_access( Heap_info_t *d );
  88. static Boolean set_up_process_low_memory_access( Heap_info_t *d );
  89. static int32 get_process_low_memory_value( void *address, int16 size );
  90. static void identify_resource( Handle map, Handle h, unsigned char *mbox_text );
  91. static void identify_block( Heap_info_handle_t h, Heap_info_t *hi, unsigned char *mbox_text );
  92.  
  93.  
  94. /*******************************************************************************
  95.  **
  96.  **    Public Variables
  97.  **
  98.  **/
  99.  
  100. /*******************************************************************************
  101.  **
  102.  **    Public Functions
  103.  **
  104.  **/
  105.  
  106. // bug in 1.7d5--ants don't display while tracking if vert scroll not at top
  107.  
  108. void Info_track_heap( EventRecord *the_event, Heap_info_handle_t h )
  109. {
  110.     Heap_info_handle_t new_h;
  111.     Heap_info_t *hi;
  112.     unsigned char *mbox_text;
  113.     int32 current_address;
  114.     Boolean current_found, mbox_needs_updating;
  115.     uns32 ticker;
  116.  
  117.     mbox_text = MBox_text();
  118.     mbox_needs_updating = false;
  119.  
  120.  
  121.     // find heap with selection, if there is one
  122.  
  123.     {
  124.         Boolean has_selection;
  125.  
  126.         h = nil;
  127.         while ( (h = l_next( heaps, h )) ) {
  128.             Heap_info_t *hi = l_access( h );
  129.             has_selection =  hi->has_selection;
  130.             l_release( h );
  131.             if ( has_selection ) break;
  132.         }
  133.     }
  134.  
  135.  
  136.     while ( StillDown() ) {
  137.  
  138.         GetMouse( &the_event->where );
  139.  
  140.  
  141.         {
  142.             Heap_info_handle_t temp_h;
  143.             Heap_info_t *hi_temp;
  144.             column_t *col;
  145.             int16 right;
  146.  
  147.             temp_h = l_next( heaps, nil );
  148.             hi_temp = l_access( temp_h );
  149.             col = Display_find_column( hi_temp, colHeap );
  150.  
  151.             right = App_window->portRect.right - 16;
  152.                 
  153.             if ( the_event->where.h >= right ) {
  154.                 Content_scroll_horiz( horiz_scroll, inDownButton, 10 );
  155.                 the_event->where.h = right;
  156.             }
  157.             else if ( the_event->where.h <= col->left ) {
  158.                 Content_scroll_horiz( horiz_scroll, inUpButton, 10 );
  159.                 the_event->where.h = col->left;
  160.             }
  161.     
  162.             l_release( temp_h );
  163.         }
  164.  
  165.  
  166.         if ( !Content_find_point( the_event->where, &new_h, nil ) ) new_h = nil;
  167.  
  168.         if ( new_h != h ) {
  169.             if ( h ) {
  170.  
  171.                 hi = l_access( h );
  172.                 hi->has_selection = false;
  173.                 Display_row( UPDATE_SELECTION, h );  // remove old selection
  174.                 l_release( h );
  175.  
  176.             }
  177.             h = new_h;
  178.         }
  179.  
  180.  
  181.         if ( h ) {
  182.  
  183.             hi = l_access( h );
  184.  
  185.             if ( !(TickCount() % 3) )
  186.                 hi->selection_phase = (hi->selection_phase + 1) & 7;
  187.  
  188.             current_address = (int32) Content_pixel_to_address( hi, the_event->where.h );
  189.             hi->has_selection = Heap_locate_block( hi, (Ptr)current_address,
  190.                     &hi->current_selection );
  191.  
  192.             if ( hi->has_selection ) {
  193.  
  194.                 if ( hi->has_selection != hi->last_has_selection ||
  195.                     (hi->current_selection.physical_start != hi->last_selection.physical_start ||
  196.                      hi->current_selection.physical_end != hi->last_selection.physical_end) ) {
  197.  
  198.                     mbox_needs_updating = true;
  199.                     mbox_type = MBOX_ADDRESS;
  200.                     phexcopy( (int32) hi->current_selection.logical_start, 8, mbox_text );
  201.                     pstrappend( "\p #", mbox_text );
  202.                     pnumappend( (int32) (hi->current_selection.logical_end -
  203.                             hi->current_selection.logical_start) + 1, mbox_text );
  204.                     pchappend( ' ', mbox_text );
  205.                     identify_block( h, hi, mbox_text );
  206.  
  207.                     hi->has_selection = true;
  208.                     record_for_mbox( hi );
  209.  
  210.                 }
  211.  
  212.             }
  213.             else if ( mbox_type != MBOX_EMPTY ) {
  214.  
  215.                 mbox_needs_updating = true;
  216.                 mbox_text[0] = 0;
  217.                 mbox_type = MBOX_EMPTY;
  218.  
  219.             }
  220.  
  221.             Display_row( UPDATE_SELECTION, h );
  222.  
  223.             l_release( h );
  224.  
  225.         }
  226.         else if ( mbox_type != MBOX_EMPTY ) {
  227.  
  228.             mbox_needs_updating = true;
  229.             mbox_text[0] = 0;
  230.             mbox_type = MBOX_EMPTY;
  231.  
  232.         }
  233.  
  234.  
  235.         if ( mbox_needs_updating ) {
  236.             mbox_needs_updating = false;
  237.             Window_update_mbox();
  238.         }
  239.  
  240.  
  241.  
  242.     for ( ticker = TickCount() + 1; ticker > TickCount(); );
  243.     }
  244. }
  245.  
  246.  
  247. static Boolean set_up_process_access( Heap_info_t *d )
  248. {
  249.     if ( !set_up_process_low_memory_access( d ) ) {
  250.         //DebugStr( "\pset_up_process_low_memory_access() failed." );
  251.         return false;
  252.     }
  253.     top_map_hdl = (Handle) get_process_low_memory_value( &TopMapHndl, 4 );
  254.     return true;
  255. }
  256.  
  257.  
  258. static Boolean set_up_process_low_memory_access( Heap_info_t *d )
  259. {
  260.     Handle lmem_hdl;
  261.  
  262.     lmem_ptr = nil;
  263.     low_memory = nil;
  264.  
  265.     lmem_hdl = GetResource( 'lmem', This_mac.hasColorQD ? NEW_lmem : OLD_lmem );
  266.     if ( !lmem_hdl ) return false;
  267.     lmem_ptr = *(lmem_elem_t **)lmem_hdl;    // assume 'lmem' resource is already locked
  268.  
  269.     if ( !get_x_process_information( d ) ) return false;
  270.     low_memory = *(**d->xinfo).processLowMemory;    // don't lock, so use is limited
  271.     return true;
  272. }
  273.  
  274.  
  275. static int32 get_process_low_memory_value( void *address, int16 size )
  276. {
  277.     lmem_elem_t *l;
  278.     Ptr value_address, start_address;
  279.     int16 run_length;
  280.     int32 value;
  281.  
  282.     if ( !low_memory ) return 0;
  283.  
  284.     l = lmem_ptr;
  285.     value_address = low_memory;
  286.     for ( ; (run_length = l->run_length); value_address += run_length, ++l ) {
  287.         start_address = l->start_address;
  288.         if ( (Ptr)address < (start_address + run_length) && (Ptr)address >= start_address ) {
  289.             value_address += (Ptr)address - start_address;
  290.             goto got_it;
  291.         }
  292.     }
  293.     value_address = (Ptr)address;    // not a saved value, so use real low memory global
  294. got_it:
  295.     for ( value = 0; size; --size ) value = (value << 8) | *(unsigned char *)value_address++;
  296.     return value;
  297. }
  298.  
  299.  
  300. typedef struct _t_resource_map {
  301.     char who_cares[16];
  302.     struct _t_resource_map **next_map_hdl;
  303.     int16 ref_num;
  304.     int16 attributes;
  305.     int16 type_list_offset;
  306.     int16 name_list_offset;
  307. } resource_map_t;
  308.  
  309. typedef struct {
  310.     int32 type;
  311.     int16 count;
  312.     int16 reference_list_offset;
  313. } resource_type_t;
  314.  
  315. typedef struct {
  316.     int16 id;
  317.     int16 name_offset;
  318.     int32 data_offset;
  319.     Handle handle;
  320. } resource_reference_t;
  321.  
  322.  
  323. static void identify_resource( Handle map, Handle h, unsigned char *mbox_text )
  324. {
  325.     resource_map_t *m;
  326.     resource_type_t *t;
  327.     resource_reference_t *r;
  328.     Ptr base_t;
  329.     int16 type_count, reference_count;
  330.  
  331.     m = *(resource_map_t **)map;
  332.     for ( ;; ) {
  333.         base_t = (Ptr)((int32)m + m->type_list_offset);
  334.         type_count = *(int16 *)base_t;
  335.         for ( t = (resource_type_t *)(base_t + 2); type_count >= 0; --type_count, ++t ) {
  336.             reference_count = t->count;
  337.             r = (resource_reference_t *)((int32)base_t + t->reference_list_offset);
  338.             for ( ; reference_count >= 0; --reference_count, ++r ) {
  339.                 if ( r->handle == h ) {
  340.  
  341.                     pchappend( ' ', mbox_text );
  342.                     pchappend( t->type >> 24, mbox_text );
  343.                     pchappend( t->type >> 16, mbox_text );
  344.                     pchappend( t->type >> 8, mbox_text );
  345.                     pchappend( t->type, mbox_text );
  346.                     pchappend( ' ', mbox_text );
  347.                     pnumappend( r->id, mbox_text );
  348. //                    pstrappend( "\p $", mbox_text );
  349. //                    phexappend( m->ref_num, 4, mbox_text );
  350.                     if ( r->name_offset != -1 ) {
  351.                         pstrappend( "\p '", mbox_text );
  352.                         pstrappend( (unsigned char *)((int32)m + m->name_list_offset + r->name_offset),
  353.                                 mbox_text );
  354.                         pchappend( '\'', mbox_text );
  355.                     }
  356.                     return;
  357.  
  358.                 }
  359.             }
  360.         }
  361.         if ( !m->next_map_hdl ) break;
  362.         m = *m->next_map_hdl;
  363.     }
  364.  
  365.     pstrappend( "\punidentifiable resource", mbox_text );
  366. }
  367.  
  368.  
  369. static void identify_block( Heap_info_handle_t h, Heap_info_t *hi, unsigned char *mbox_text )
  370. {
  371.     if ( !(hi->current_selection.type & BLOCK_TYPE_NOT_FREE_MASK) ) {    // free block
  372.         pstrappend( "\pfree", mbox_text );
  373.     }
  374.  
  375.  
  376.     else if ( h == multifinder ) {
  377.         pstrappend( "\pmf block", mbox_text );
  378.         // identify multifinder apps and blocks allocated by apps
  379.     }
  380.  
  381.  
  382.     else if ( h == system ) {
  383.         if ( (hi->current_selection.flags & BLOCK_FLAG_RESOURCE_MASK) )
  384.             identify_resource( SysMapHndl, hi->current_selection.handle, mbox_text );
  385.         else {
  386.             // identify system block
  387.             pstrappend( "\psystem block", mbox_text );
  388.         }
  389.     }
  390.  
  391.  
  392.     else if ( hi->info.processNumber.highLongOfPSN ||
  393.             hi->info.processNumber.lowLongOfPSN != kNoProcess ) {
  394.  
  395.     // $01234567 CODE 2 'Main'
  396.  
  397.         if ( set_up_process_access( hi ) ) {
  398.  
  399.             if ( (hi->current_selection.flags & BLOCK_FLAG_RESOURCE_MASK) )
  400.                 identify_resource( top_map_hdl, hi->current_selection.handle, mbox_text );
  401.             else {
  402.                 // identify app block
  403.                 pstrappend( "\papp block", mbox_text );
  404.             }
  405.         }
  406.     }
  407. }
  408.